﻿// --------------------------------
// <copyright file="GraphAPIObjects.cs" company="Samaj Shekhar">
//     Copyright (c) 2010-2011 Samaj Shekhar
// </copyright>
// <author>Samaj Shekhar (samaj.shekhar@hotmail.com)</author>
// <license>Released under the terms of the Microsoft Public License (Ms-PL)</license>
// <website>http://thesharepage.codeplex.com</website>
// ---------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharePage.CoreLib.Utils.ExtentionMethods;

//This namespace contains classes that map to the structure of Json objects returned by Graph API Call
//It can be used by JavascriptSerializer to Deserialize the Json objects returned
//and convert them to .Net Class equivalent
namespace SharePage.CoreLib.Facebook.GraphAPIObjects
{

    //Region enclosing Facebook feed class for use in calls without access token and Classes specific to Facebook Feed
    #region FacebookFeedWithNoAccessToken

    /// <summary>
    /// <para>Represents a class which maps to Json objects of feeds returned by Graph API call to</para>
    /// <para>https://graph.facebook.com/[username]|[userID]/feeds </para>
    /// <para>Without using a access token</para>
    /// </summary>
    /// <remarks>
    /// Copyright: Copyright (c) 2010-2011 Samaj Shekhar
    /// Last Update: 28-Dec-2010|01:46am
    /// </remarks>
    [Serializable]
    public class FacebookFeedsWithoutToken
    {
        /// <summary>
        /// Contains array of feeds recived without using access token
        /// </summary>
        public FacebookFeedWithoutToken[] data { get; set; }

        /// <summary>
        /// Contains paging links
        /// </summary>
        public ReturnedDataPaging paging { get; set; }
    }

    /// <summary>
    /// <para>Represents a class which maps to one single feed returned by Graph API call to</para>
    /// <para>https://graph.facebook.com/[feedID]</para>
    /// <para>Without using a access token</para>
    /// </summary>
    [Serializable]
    public class FacebookFeedWithoutToken
    {
        /// <summary>
        /// Feed id
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// Name and ID of the sending user
        /// </summary>
        public NameIdPair from { get; set; }

        /// <summary>
        /// List of profiles mentioned in post
        /// </summary>
        public PostedTo to { get; set; }

        /// <summary>
        /// The message
        /// </summary>
        public string message { get; set; }

        /// <summary>
        /// Link to the picture
        /// </summary>
        public Uri picture { get; set; }

        /// <summary>
        /// A link attached to the post
        /// </summary>
        public Uri link { get; set; }

        /// <summary>
        /// The name of the link
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// Caption of the link (appears beneth the link name)
        /// </summary>
        public string caption { get; set; }

        /// <summary>
        /// A description ogf the link (appears beneth the link caption)
        /// </summary>
        public string description { get; set; }

        /// <summary>
        /// A link to an icon representing the type of the post
        /// </summary>
        public Uri icon { get; set; }

        /// <summary>
        /// A list of available actions on the post
        /// </summary>
        public NameLinkPair[] actions { get; set; }

        /// <summary>
        /// Type of the post like a Share, link, status, etc (Not mentioned in graph api documentation)
        /// </summary>
        public string type { get; set; }

        /// <summary>
        /// Name and ID of the application which posted the post. (Similar to attribution which is available with access token)
        /// </summary>
        public NameIdPair application { get; set; }

        /// <summary>
        /// The time the post was initially created
        /// </summary>
        public DateTime created_time { get; set; }

        /// <summary>
        /// The time of the last comment on this post
        /// </summary>
        public DateTime updated_time { get; set; }

        /// <summary>
        /// The list of likes on this post with count
        /// </summary>
        public FacebookPostLikes likes { get; set; }

        /// <summary>
        /// The list of comments on this post
        /// </summary>
        public FacebookPostComments comments { get; set; }

        /// <summary>
        /// Properties of the post, usually found in type photo post
        /// </summary>
        public FacebookPostProperty[] properties { get; set; }

        // Not Sure its available in feed without access token or not
        ///// <summary>
        ///// A URL to the flash movie or video file embeded in post
        ///// </summary>
        //public Uri source { get; set; }
    }

    /// <summary>
    /// <para>This class represents a Facebook Post's likes retrived by Graph API call to</para>
    /// <para>http://graph.facebook.com/[Post ID]/likes</para>
    /// </summary>
    [Serializable]
    public class FacebookPostLikes
    {
        /// <summary>
        /// A user name and Id pair of the user liking the post
        /// </summary>
        public NameIdPair[] data { get; set; }

        /// <summary>
        /// Total count of the like on the post
        /// </summary>
        public int count { get; set; }
    }    

    /// <summary>
    /// <para>This class represents Comments on the Facebook post with count. retrived by Graph API call to</para>
    /// <para>http://graph.facebook.com/[Post ID]/comments</para>
    /// </summary>
    [Serializable]
    public class FacebookPostComments
    {
        /// <summary>
        /// A single facebook comment of type FacebookPostComment
        /// </summary>
        public FacebookPostComment[] data { get; set; }

        /// <summary>
        /// Total number of comments on the post
        /// </summary>
        public int count { get; set; }
    }

    /// <summary>
    /// <para>Represents a single Facebook post comment, can be queried by a Graph API call to</para>
    /// <para>http://graph.facebook.com/[Comment ID]</para>
    /// </summary>
    [Serializable]
    public class FacebookPostComment
    {
        /// <summary>
        /// Comment id
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// User name and Id posting the comment
        /// </summary>
        public NameIdPair from { get; set; }

        /// <summary>
        /// The comment text
        /// </summary>
        public string message { get; set; }

        /// <summary>
        /// Time the comment was posted
        /// </summary>
        public DateTime created_time { get; set; }
    }

    /// <summary>
    /// A facebook post property (not mentioned in Graph API)
    /// </summary>
    [Serializable]
    public class FacebookPostProperty
    {
        public string name { get; set; }
        public string text { get; set; }
        public Uri href { get; set; }
    }

    #endregion FacebookFeedWithNoAccessToken

    /// <summary>
    /// Name id pair of user post was posted to
    /// </summary>
    [Serializable]
    public class PostedTo
    {
        public NameIdPair[] data { get; set; }
    }

    /// <summary>
    /// I simple Name and Id pair
    /// </summary>
    [Serializable]
    public class NameIdPair
    {
        /// <summary>
        /// A name of type string
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// A id of type string
        /// </summary>
        public string id { get; set; }
    }

    /// <summary>
    /// A pair of name and Link
    /// </summary>
    [Serializable]
    public class NameLinkPair
    {
        /// <summary>
        /// A name of type string
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// A link of type Uri
        /// </summary>
        public Uri link { get; set; }
    }

    /// <summary>
    /// A Paging object containing uri link to Previous page and Next page
    /// </summary>
    [Serializable]
    public class ReturnedDataPaging
    {
        /// <summary>
        /// Uri for the previous page
        /// </summary>
        public Uri previous { get; set; }

        /// <summary>
        /// Uri for next page
        /// </summary>
        public Uri next { get; set; }
    }

    //Region enclosing Facebook feed class for use in calls with access token and Classes specific to Facebook Feed
    #region FacebookFeedWithAccessToken

    /// <summary>
    /// <para>Represents a class which maps to Json objects of feeds returned by Graph API call to</para>
    /// <para>https://graph.facebook.com/[username]|[userID]/feeds?[access token] </para>
    /// <para>With a valid access token</para>
    /// </summary>
    /// <remarks>
    /// Copyright: Copyright (c) 2010-2011 Samaj Shekhar
    /// Last Update: 30-Dec-2010|05:19pm
    /// </remarks>
    [Serializable]
    public class FacebookFeedsWithAccessToken
    {
        /// <summary>
        /// Array of facebook feeds recived using access token
        /// </summary>
        public FacebookFeedWithAccessToken[] data { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public ReturnedDataPaging paging { get; set; }
    }

    /// <summary>
    /// <para>Represents a class which maps to one single feed returned by Graph API call to</para>
    /// <para>https://graph.facebook.com/[feedID]?[access token]</para>
    /// <para>With a valid access token</para>
    /// </summary>
    /// <remarks>
    /// <para>Couldn't Inherit above class because Jaavscript serializer Raises AmbiguityMatchException for int like property</para> 
    /// </remarks>
    [Serializable]
    public class FacebookFeedWithAccessToken //: FacebookFeedWithoutToken
    {

        /// <summary>
        /// Feed id
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// Name and ID of the sending user
        /// </summary>
        public NameIdPair from { get; set; }

        /// <summary>
        /// List of profiles mentioned in post
        /// </summary>
        public PostedTo to { get; set; }

        /// <summary>
        /// The message
        /// </summary>
        public string message { get; set; }

        /// <summary>
        /// Link to the picture
        /// </summary>
        public Uri picture { get; set; }

        /// <summary>
        /// A link attached to the post
        /// </summary>
        public Uri link { get; set; }

        /// <summary>
        /// The name of the link
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// Caption of the link (appears beneth the link name)
        /// </summary>
        public string caption { get; set; }

        /// <summary>
        /// A description ogf the link (appears beneth the link caption)
        /// </summary>
        public string description { get; set; }

        /// <summary>
        /// A link to an icon representing the type of the post
        /// </summary>
        public Uri icon { get; set; }

        /// <summary>
        /// A list of available actions on the post
        /// </summary>
        public NameLinkPair[] actions { get; set; }

        /// <summary>
        /// Type of the post like a Share, link, status, etc (Not mentioned in graph api documentation)
        /// </summary>
        public string type { get; set; }

        /// <summary>
        /// The time the post was initially created
        /// </summary>
        public DateTime created_time { get; set; }

        /// <summary>
        /// The time of the last comment on this post
        /// </summary>
        public DateTime updated_time { get; set; }

        /// <summary>
        /// The list of comments on this post
        /// </summary>
        public FacebookPostComments comments { get; set; }

        /// <summary>
        /// Properties of the post, usually found in type photo post
        /// </summary>
        public FacebookPostProperty[] properties { get; set; }

        /// <summary>
        /// Number of likes for the post (Hides property in base class)
        /// </summary>
        public new int likes { get; set; }

        /// <summary>
        /// Privasy specification of the post
        /// </summary>
        public FacebookObjectPrivacy privacy { get; set; }

        /// <summary>
        /// A string representing which application was used to create this post.
        /// </summary>
        public string attribution { get; set; }
    }

   #endregion FacebookFeedWithAccessToken

    /// <summary>
    /// This class represents the Facebook privacy object
    /// </summary>
    [Serializable]
    public class FacebookObjectPrivacy
    {
        /// <summary>
        /// Contains a description test of whom to allow and deny
        /// </summary>
        public string description { get; set; }

        /// <summary>
        /// On of the possible values of FacebookPrivacy.PrivacyTypes
        /// </summary>
        public string value { get; set; }//Couldn't find a way to make Enums serializable so using string but privacy enum can be used to compare

        /// <summary>
        /// Description ofFriends who can see
        /// </summary>
        public string friends { get; set; }

        /// <summary>
        /// CSV list of Uid of friends who are allowed
        /// </summary>
        public string allow { get; set; }

        /// <summary>
        /// CSV list of Uid of users who are denied
        /// </summary>
        public string deny { get; set; }

        ///// <summary>
        ///// Description not available
        ///// </summary>
        //public string networks { get; set; } //Data type not known, so commented out untill known
    }

    /// <summary>
    /// Encapsulates Facebook Privacy types
    /// </summary>
    [Serializable]
    public class FacebookPrivacy
    {
        /// <summary>
        /// Contains the enumeration of Different Facebook Privacy Types
        /// </summary>
        public enum PrivacyTypes
        {
            /// <summary>
            /// Visible to Everyone
            /// </summary>            
            EVERYONE,

            /// <summary>
            /// Visible to Custom list of friends
            /// </summary>
            CUSTOM,

            /// <summary>
            /// Visible to Friends only
            /// </summary>
            ALL_FRIENDS,

            /// <summary>
            /// Visible to Network Friends
            /// </summary>
            NETWORKS_FRIENDS,

            /// <summary>
            /// Visible to Friends and Friends of Friends
            /// </summary>
            FRIENDS_OF_FRIENDS
        }

        /// <summary>
        /// Gets the name of the Privacy type as a string
        /// </summary>
        /// <param name="type">Privacy type to convert</param>
        /// <returns>Returns Privacy type as a string</returns>
        public static string ToString(FacebookPrivacy.PrivacyTypes type)
        {
            return Enum.GetName(typeof(FacebookPrivacy.PrivacyTypes), type);
        }
    }

    //Region encloss facebook user likes class
    #region FacebookUserLikeClass

    /// <summary>
    /// A class that represent a collection of facebook user likes
    /// </summary>
    [Serializable]
    public class FacebookUserLikes
    {
        /// <summary>
        /// A collection of facebook user likes
        /// </summary>
        public FacebookUserLike[] data { get; set; }

        /// <summary>
        /// Data paging links, user like normally return only next link
        /// </summary>
        public ReturnedDataPaging paging { get; set; }
    }

    /// <summary>
    /// A class that represent a Facebook user like
    /// </summary>
    [Serializable]
    public class FacebookUserLike
    {
        /// <summary>
        /// Name of the like
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// Category of the like. Like an Application, Local Business, Interest
        /// </summary>
        public string category { get; set; }

        /// <summary>
        /// ID of the object liked
        /// </summary>
        public string id { get; set; }

        /// <summary>
        /// Date and time the object was liked 
        /// </summary>
        public DateTime created_time { get; set; }
    }

    #endregion FacebookUserLikeClass    

    //Region encloses Facebook Exception mapping to Json exception returned in GraphAPI call.
    #region FacebookExceptionClass

    /// <summary>
    /// A class mapping closely to facebook exception Json returned in Graph API call
    /// </summary>
    public class FacebookException
    {
        /// <summary>
        /// The error object containing Message and type of error
        /// </summary>
        public FacebookError error { get; set; }
    }

    /// <summary>
    /// The class containing Message and type of error
    /// </summary>
    public class FacebookError
    {
        /// <summary>
        /// The Type of error
        /// </summary>
        public string type { get; set; }

        /// <summary>
        /// The Message recived in Exception
        /// </summary>
        public string message { get; set; }
    }

    #endregion FacebookExceptionClass
}
